home *** CD-ROM | disk | FTP | other *** search
- //**************************************************
- // Listing 3
- //
- // FILE NAME : sema.cpp
- // AUTHOR : Matt Weisfeld
- //
- // DESCRIPTION : using semaphores and critical
- // sections to synchronize processes.
- //
- //**************************************************
- // Example : For 3 processes
- //
- // Pn - process (P0 is the master)
- // T - turn variable
- // Sn - status
- //
- // P0 P1 P2 T S1 S2
- //
-
- #include <iostream.h>
- #include <stdlib.h>
- #include <string.h>
- #include "sema.h"
-
- // DESCRIPTION : constructor
- semaphore::semaphore (long processes)
- {
- strcpy (filename,FILENAME);
-
- // Initialize the number of processess and the
- // appropriate arrays.
- PROCESSES = processes;
- for (int loop_i = 0; loop_i < PROCESSES; loop_i++) {
- NODE[loop_i] = loop_i;
- LOC[loop_i] = PROCESSES+loop_i;
- };
- };
-
- // DESCRIPTION : dummy destructor
- semaphore::~semaphore(void){};
-
- // DESCRIPTION : synchronize using critical sections
- void semaphore::synchronize(char *param) {
-
- // If the parameter is an 'i', simply initialize
- // the shared file then exit
- if (!strcmp (param, "i")) {
- initialize();
- exit(0);
- };
-
- node = atoi(param); // identify the current node
- intro(); // print out informational messages
- i = node; // use 'i' since algorithm does
- turn_num=0;
- flag_num=0;
- critical_status=NORMAL;
-
- // Perform critical function until exit condition exists
- while (critical_status == NORMAL) {
- perform();
- }
- return;
- }
-
- // DESCRIPTION : contains the CS algorithm
- void semaphore::perform(void)
- {
-
- // A do-while (!expression) is the same as
- // do-until (expression)
-
- // See algorithm for description of the code.
-
- do {
-
- cs_write ( i, WANT_IN);
-
- turn_num = cs_read ( LOC[0]);
-
- j = turn_num;
-
- while (j != i) {
-
- flag_num = cs_read ( j);
-
- if (flag_num != IDLE) {
-
- turn_num = cs_read ( LOC[0]);
-
- j = turn_num;
-
- } else {
-
-
- j = (j+1) % PROCESSES;
-
-
- }
-
- }
-
- cs_write ( i, IN_CS);
-
-
- j = 0;
-
- flag_num = cs_read ( j);
-
- while ( (j<PROCESSES-1) && (j==i || flag_num!=IN_CS) ) {
-
- j++;
-
- flag_num = cs_read ( j);
-
- }
-
- turn_num = cs_read ( LOC[0]);
-
- flag_num = cs_read ( turn_num);
-
- }while (!((j>=PROCESSES-1) && ((turn_num == i) || flag_num == IDLE)));
-
- turn_num = i;
-
- cs_write ( LOC[0], turn_num);
-
-
- // enter critical section
-
- critical_status = critical_section();
-
- // leave critical section
-
- turn_num = cs_read ( LOC[0]);
-
- j = (turn_num+1) % PROCESSES;
-
- flag_num = cs_read ( j);
-
- while (flag_num == IDLE) {
-
- j = (j+1) % PROCESSES;
-
- flag_num = cs_read ( j);
-
- }
-
- turn_num = j;
-
- cs_write ( LOC[0], turn_num);
-
- flag_num = IDLE;
-
- cs_write ( i, flag_num);
-
- return;
- };
-
- // DESCRIPTION : identify the node
- void semaphore::intro(void)
- {
-
- printf ("PROCESSOR NODE %d\n", node);
-
- return;
-
- };
-
- // DESCRIPTION : initialize the shared data file
- void semaphore::initialize(void) {
-
- FILE *fp;
- long loc = 0, zero=0;
-
- printf ("Initialize\n");
-
- if ((fp = fopen(filename, "w+")) == NULL){
- printf ("initialize: can't open %s\n", filename);
- exit(0);
- };
-
- // Initialize all status variables and flags to zero
- for (loc = 0; loc < (PROCESSES + 1 + (PROCESSES-1)); loc++) {
-
- if (fseek (fp, loc*2, ORIGIN) != 0) {
- printf ("ERROR: fseek error in initialize\n");
- exit(0);
- };
-
- if (fprintf (fp, "%ld ", zero) < 0) {
- printf ("ERROR: initialize error\n");
- exit(0);
- };
-
- };
-
- // Simply for clarity, mark the end of the flags with
- // an 'X'
- if (fseek (fp, loc*2, ORIGIN) != 0) {
- printf ("ERROR: fseek error in initialize\n");
- exit(0);
- };
-
- if (fprintf (fp, "%c ", 'X') < 0) {
- printf ("ERROR: initialize error\n");
- exit(0);
- };
-
- fclose (fp);
-
- };
-
- // DESCRIPTION : actual critical section
- long semaphore::critical_section(void)
- {
- int loop_i;
- long status;
-
- // If the node is the master (node 0) then see if all
- // other nodes are ready. If they are, then clear all
- // appropriate variables and the shared file. If all
- // not ready, try again.
-
- if (node == 0) {
-
- status = READY;
- for (loop_i=1; loop_i<PROCESSES; loop_i++) {
- NODE_NUM[loop_i] = cs_read(LOC[loop_i]);
- if (NODE_NUM[loop_i] != READY)
- status=CLEAR;
- };
-
- if (status == READY) {
- for (loop_i=1; loop_i<PROCESSES; loop_i++) {
-
- NODE_NUM[loop_i] = CLEAR;
- cs_write(LOC[loop_i], NODE_NUM[loop_i]);
- }
- return(STOP);
-
- } else {
-
- return(NORMAL);
-
- }
-
- } else { // if non-master node, mark node as ready
-
- NODE_NUM[node] = READY;
- cs_write(LOC[node], NODE_NUM[node]);
- return(STOP);
- }
- };
-
- // DESCRIPTION : write to the shared file
- void semaphore::cs_write(long loc, long value)
- {
- FILE *fp;
-
- if ((fp = fopen(filename, "r+")) == NULL){
- printf ("cs_write: can\'t open %s\n", filename);
- exit(0);
- };
-
- if (fseek (fp, loc*2, ORIGIN) != 0) {
- printf ("ERROR: fseek error in cs_write\n");
- exit(0);
- };
-
- if (fprintf (fp, "%ld ", value) < 0) {
- printf ("ERROR: cs_write error\n");
- exit(0);
- };
-
- fclose (fp);
-
- return;
- };
-
- // DESCRIPTION : read from the shared file
- long semaphore::cs_read(long loc)
- {
-
- FILE *fp;
- long value;
-
- if ((fp = fopen(filename, "r")) == NULL){
-
- printf ("cs_read: can't open %s\n", filename);
- exit(0);
-
- };
-
- if (fseek (fp, loc*2, ORIGIN) != 0)
- printf ("ERROR: fseek error in cs_read\n");
- if (fscanf (fp ,"%ld", &value) == EOF)
- printf ("ERROR: cs_read error\n");
-
- fclose (fp);
-
- return(value);
- };
-
-